package thread;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import object.Dialogue;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import voice.main.ChatFragment;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;

public class SpeechToTextTask extends AsyncTask<String, Void, String>{
	private ChatFragment context;
	public SpeechToTextTask(ChatFragment context) {
		this.context = context;
		Log.v("Constructor", "Begin Constructor");
    }
	
	public static byte[] convertStreamToByteArray(FileInputStream is) throws IOException {
	    ByteArrayOutputStream baos = new ByteArrayOutputStream();
	    byte[] buff = new byte[10240];
	    int i = Integer.MAX_VALUE;
	    while ((i = is.read(buff, 0, buff.length)) > 0) {
	        baos.write(buff, 0, i);
	    }
	    return baos.toByteArray(); 
	}
	
    protected String doInBackground(String... filename) {
		try 
		{
			Log.v("Background", "Begin background");
			
			File file = new File(Environment.getExternalStorageDirectory().toString() + "/" + filename[0]);
            byte[] bytes = FileUtils.readFileToByteArray(file);
			String encodedFile = Base64.encodeToString(bytes, Base64.DEFAULT);
            
            HttpClient httpClient = new DefaultHttpClient();
            HttpPost postRequest = new HttpPost("http://www.ailab.hcmus.edu.vn/ASRDemo/Service.asmx?op=ASR");
            postRequest.setHeader("SOAPAction", "http://www.ailab.hcmus.edu.vn/ASRDemo/ASR");
            postRequest.setHeader("Content-Type", "text/xml; charset=utf-8");
            
            StringBuffer body = new StringBuffer();
	        body.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
	        body.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
	        body.append("<soap:Body>");
	        body.append("<ASR xmlns=\"http://www.ailab.hcmus.edu.vn/ASRDemo\">");
	        body.append("<byteOfWave>" + encodedFile + "</byteOfWave>");
	        body.append("<czt>" + "asrdemo" + "</czt>");
	        body.append("</ASR>");
	        body.append("</soap:Body>");
	        body.append("</soap:Envelope>");
	        postRequest.setEntity(new StringEntity(body.toString()));
	        
            HttpResponse response = httpClient.execute(postRequest);
            StatusLine statusLine = response.getStatusLine();
    	    if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
    	    	
    	    	String r_entity = EntityUtils.toString(response.getEntity());
                
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = dbf.newDocumentBuilder();
                Document doc = db.parse(new ByteArrayInputStream(r_entity.getBytes("UTF-8")));
                XPathFactory xPathfactory = XPathFactory.newInstance();
                XPath xpath = xPathfactory.newXPath();
                XPathExpression expr = xpath.compile("//ASRResult");
                NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

                return nl.item(0).getTextContent();
    	    	
    	    } 
    	    else {
    	    	return "Bad Response.";
    	    }
            
		} 
		catch (UnsupportedEncodingException e1) {
	    	return "Encoding UTF-8 is not supported.";
		}
		catch (ClientProtocolException e) {
	    	return "Failed to connect to server. (HTTP Protocol Error)";
    	} 
		catch (IOException e) {
	    	return "Failed to connect to server. (Connection Aborted)";
    	} 
		catch (ParserConfigurationException e) {
    		return "Bad Response.";
		} 
		catch (SAXException e) {
			return "Bad Response.";
		} 
		catch (XPathExpressionException e) {
			return "Bad Response.";
		}
    }
    protected void onPostExecute(String response) {
    	Log.v("Post", "Post execute");
		context.adapter.add(new Dialogue(true, '"' + response + '"'));
		new RetrieveAIMLTask(context).execute(response);
    }
}
